package service

import (
	"awesomeProject/internal/config"
	"awesomeProject/pkg/errors"
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"strings"
	"time"
)

// AIService AI服务接口
type AIService interface {
	// AutoClassify 自动分类文章
	AutoClassify(ctx context.Context, title, content string) (string, error)
	// GenerateSummary 生成文章摘要
	GenerateSummary(ctx context.Context, content string) (string, error)
	// AnswerQuestion 问答功能
	AnswerQuestion(ctx context.Context, question, context string) (string, error)
	// GenerateEmbedding 生成文本嵌入向量
	GenerateEmbedding(ctx context.Context, text string) ([]float64, error)
	// SmartClassify 智能分类管理（检查现有分类或创建新分类）
	SmartClassify(ctx context.Context, title, content string, existingCategories []string) (categoryName, description string, isNew bool, error error)
}

type aiService struct {
	config *config.AIConfig
	client *http.Client
}

// NewAIService 创建AI服务实例
func NewAIService(cfg *config.AIConfig) AIService {
	return &aiService{
		config: cfg,
		client: &http.Client{
			Timeout: 30 * time.Second,
		},
	}
}

// ARK API请求结构
type ARKRequest struct {
	Model    string    `json:"model"`
	Messages []Message `json:"messages"`
	Stream   bool      `json:"stream"`
}

type Message struct {
	Role    string `json:"role"`
	Content string `json:"content"`
}

// ARK API响应结构
type ARKResponse struct {
	Choices []Choice `json:"choices"`
	Usage   Usage    `json:"usage"`
}

type Choice struct {
	Message      Message `json:"message"`
	FinishReason string  `json:"finish_reason"`
}

type Usage struct {
	PromptTokens     int `json:"prompt_tokens"`
	CompletionTokens int `json:"completion_tokens"`
	TotalTokens      int `json:"total_tokens"`
}

// Embedding API请求结构
type EmbeddingRequest struct {
	Model string   `json:"model"`
	Input []string `json:"input"`
}

// Embedding API响应结构
type EmbeddingResponse struct {
	Data  []EmbeddingData `json:"data"`
	Usage Usage           `json:"usage"`
}

type EmbeddingData struct {
	Embedding []float64 `json:"embedding"`
	Index     int       `json:"index"`
}

// callARKAPI 调用ARK API
func (s *aiService) callARKAPI(ctx context.Context, messages []Message) (string, error) {
	req := ARKRequest{
		Model:    s.config.MODEL,
		Messages: messages,
		Stream:   false,
	}

	jsonData, err := json.Marshal(req)
	if err != nil {
		return "", errors.New(errors.AIServiceError, "Failed to marshal request", err.Error())
	}

	httpReq, err := http.NewRequestWithContext(ctx, "POST", "https://ark.cn-beijing.volces.com/api/v3/chat/completions", bytes.NewBuffer(jsonData))
	if err != nil {
		return "", errors.New(errors.AIServiceError, "Failed to create request", err.Error())
	}

	httpReq.Header.Set("Content-Type", "application/json")
	httpReq.Header.Set("Authorization", "Bearer "+s.config.ARKAPIKEY)

	resp, err := s.client.Do(httpReq)
	if err != nil {
		return "", errors.New(errors.AIServiceError, "Failed to call ARK API", err.Error())
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", errors.New(errors.AIServiceError, "Failed to read response", err.Error())
	}

	if resp.StatusCode != http.StatusOK {
		return "", errors.New(errors.AIServiceError, fmt.Sprintf("ARK API returned status %d", resp.StatusCode), string(body))
	}

	var arkResp ARKResponse
	if err := json.Unmarshal(body, &arkResp); err != nil {
		return "", errors.New(errors.AIServiceError, "Failed to unmarshal response", err.Error())
	}

	if len(arkResp.Choices) == 0 {
		return "", errors.New(errors.AIServiceError, "No choices in response", "")
	}

	return arkResp.Choices[0].Message.Content, nil
}

// AutoClassify 自动分类文章
func (s *aiService) AutoClassify(ctx context.Context, title, content string) (string, error) {
	prompt := fmt.Sprintf(`请根据以下文章的标题和内容，为文章确定一个合适的分类名称。分类名称应该简洁明了，能够准确反映文章的主题。

标题：%s
内容：%s

请只返回分类名称，不要包含其他内容。例如："技术分享"、"生活随笔"、"学习笔记"等。`, title, content)

	messages := []Message{
		{
			Role:    "user",
			Content: prompt,
		},
	}

	result, err := s.callARKAPI(ctx, messages)
	if err != nil {
		return "", err
	}

	// 清理结果
	result = strings.TrimSpace(result)
	if result == "" {
		return "其他", nil
	}

	return result, nil
}

// GenerateSummary 生成文章摘要
func (s *aiService) GenerateSummary(ctx context.Context, content string) (string, error) {
	prompt := fmt.Sprintf(`请为以下文章生成一个简洁的摘要，控制在100字以内：

%s

请只返回摘要内容，不要包含其他说明。`, content)

	messages := []Message{
		{
			Role:    "user",
			Content: prompt,
		},
	}

	return s.callARKAPI(ctx, messages)
}

// AnswerQuestion 问答功能
func (s *aiService) AnswerQuestion(ctx context.Context, question, contextInfo string) (string, error) {
	prompt := fmt.Sprintf(`基于以下上下文信息回答问题：

上下文：%s

问题：%s

请提供准确、有用的回答。`, contextInfo, question)

	messages := []Message{
		{
			Role:    "user",
			Content: prompt,
		},
	}

	return s.callARKAPI(ctx, messages)
}

// GenerateEmbedding 生成文本嵌入向量
func (s *aiService) GenerateEmbedding(ctx context.Context, text string) ([]float64, error) {
	req := EmbeddingRequest{
		Model: s.config.EMBEDDER,
		Input: []string{text},
	}

	jsonData, err := json.Marshal(req)
	if err != nil {
		return nil, errors.New(errors.AIServiceError, "Failed to marshal embedding request", err.Error())
	}

	httpReq, err := http.NewRequestWithContext(ctx, "POST", "https://ark.cn-beijing.volces.com/api/v3/embeddings", bytes.NewBuffer(jsonData))
	if err != nil {
		return nil, errors.New(errors.AIServiceError, "Failed to create embedding request", err.Error())
	}

	httpReq.Header.Set("Content-Type", "application/json")
	httpReq.Header.Set("Authorization", "Bearer "+s.config.ARKAPIKEY)

	resp, err := s.client.Do(httpReq)
	if err != nil {
		return nil, errors.New(errors.AIServiceError, "Failed to call embedding API", err.Error())
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, errors.New(errors.AIServiceError, "Failed to read embedding response", err.Error())
	}

	if resp.StatusCode != http.StatusOK {
		return nil, errors.New(errors.AIServiceError, fmt.Sprintf("Embedding API returned status %d", resp.StatusCode), string(body))
	}

	var embResp EmbeddingResponse
	if err := json.Unmarshal(body, &embResp); err != nil {
		return nil, errors.New(errors.AIServiceError, "Failed to unmarshal embedding response", err.Error())
	}

	if len(embResp.Data) == 0 {
		return nil, errors.New(errors.AIServiceError, "No embedding data in response", "")
	}

	return embResp.Data[0].Embedding, nil
}

// SmartClassify 智能分类管理（检查现有分类或创建新分类）
func (s *aiService) SmartClassify(ctx context.Context, title, content string, existingCategories []string) (categoryName, description string, isNew bool, error error) {
	// 构建现有分类列表字符串
	existingCategoriesStr := strings.Join(existingCategories, "、")
	
	var prompt string
	if len(existingCategories) > 0 {
		prompt = fmt.Sprintf(`请分析以下文章的标题和内容，并执行以下任务：

1. 首先检查文章是否适合归入现有分类：%s
2. 如果适合现有分类，请返回格式："EXISTING|分类名称"
3. 如果不适合任何现有分类，请创建一个新的分类，返回格式："NEW|新分类名称|分类描述"

标题：%s
内容：%s

注意：
- 分类名称应简洁明了（2-6个字）
- 分类描述应准确概括该类文章的特点（10-30个字）
- 优先使用现有分类，只有在确实不合适时才创建新分类`, existingCategoriesStr, title, content)
	} else {
		prompt = fmt.Sprintf(`请为以下文章创建一个合适的分类：

标题：%s
内容：%s

请返回格式："NEW|分类名称|分类描述"

注意：
- 分类名称应简洁明了（2-6个字）
- 分类描述应准确概括该类文章的特点（10-30个字）`, title, content)
	}

	messages := []Message{
		{
			Role:    "user",
			Content: prompt,
		},
	}

	result, err := s.callARKAPI(ctx, messages)
	if err != nil {
		return "", "", false, err
	}

	// 解析AI返回的结果
	result = strings.TrimSpace(result)
	parts := strings.Split(result, "|")
	
	if len(parts) < 2 {
		// 如果格式不正确，默认创建"其他"分类
		return "其他", "未分类的文章", true, nil
	}

	if parts[0] == "EXISTING" {
		// 使用现有分类
		return parts[1], "", false, nil
	} else if parts[0] == "NEW" && len(parts) >= 3 {
		// 创建新分类
		return parts[1], parts[2], true, nil
	}

	// 默认情况
	return "其他", "未分类的文章", true, nil
}